package io.sdl.common.utils;

import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.*;
import java.time.LocalDate;
import java.util.UUID;

/**
 * 文件上传工具类
 */
public class UploadFileUtils {

    // 默认上传目录（可通过set方法覆盖）
    private static String defaultBaseDir = "uploads";

    // 允许的文件扩展名（白名单）
    private static final String[] ALLOWED_EXTENSIONS = {
            "jpg", "jpeg", "png", "gif", "pdf", "doc", "docx"
    };

    /**
     * 上传单个文件
     * @param file 上传的文件对象
     * @return 相对路径（如：2023-08-20/uuid_filename.jpg）
     * @throws IOException 文件操作异常
     * @throws IllegalArgumentException 非法文件类型
     */
    public static String uploadFile(MultipartFile file) throws IOException {
        return uploadFile(file, defaultBaseDir);
    }

    /**
     * 上传单个文件到指定目录
     * @param file 上传的文件对象
     * @param baseDir 基础存储目录
     * @return 相对路径
     * @throws IOException 文件操作异常
     * @throws IllegalArgumentException 非法文件类型
     */
    public static String uploadFile(MultipartFile file, String baseDir) throws IOException {
        // 1. 参数校验
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }

        // 2. 安全检查
        String originalFilename = file.getOriginalFilename();
        String fileExtension = getFileExtension(originalFilename);
        if (!isAllowedExtension(fileExtension)) {
            throw new IllegalArgumentException("不支持的文件类型: " + fileExtension);
        }

        // 3. 生成存储路径
        String dateDir = LocalDate.now().toString();
        String uuid = UUID.randomUUID().toString();
        String safeFileName = uuid + "_" + sanitizeFilename(originalFilename);
        String relativePath = dateDir + "/" + safeFileName;


        // 4. 创建目标目录
        Path fullPath = Paths.get(baseDir, relativePath).toAbsolutePath().normalize();
        Files.createDirectories(fullPath.getParent());

        // 5. 保存文件
        Files.copy(file.getInputStream(), fullPath, StandardCopyOption.REPLACE_EXISTING);

        return relativePath;
    }

    /**
     * 上传多个文件
     * @param files 文件数组
     * @return 相对路径数组
     * @throws IOException 文件操作异常
     */
    public static String[] uploadFiles(MultipartFile[] files) throws IOException {
        if (files == null || files.length == 0) {
            return new String[0];
        }

        String[] paths = new String[files.length];
        for (int i = 0; i < files.length; i++) {
            paths[i] = uploadFile(files[i]);
        }
        return paths;
    }

    /**
     * 设置默认上传目录
     * @param dir 目录路径
     */
    public static void setDefaultBaseDir(String dir) {
        defaultBaseDir = dir;
    }

    // ============== 私有工具方法 ==============

    private static String getFileExtension(String filename) {
        if (filename == null) {
            return null;
        }
        int dotIndex = filename.lastIndexOf('.');
        return (dotIndex == -1) ? "" : filename.substring(dotIndex + 1).toLowerCase();
    }

    private static boolean isAllowedExtension(String extension) {
        if (extension == null || extension.isEmpty()) {
            return false;
        }
        for (String allowed : ALLOWED_EXTENSIONS) {
            if (allowed.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        return false;
    }

    private static String sanitizeFilename(String filename) {
        return filename.replaceAll("[^a-zA-Z0-9._-]", "_");
    }
}